package com.aryankh.aspect;

import com.aryankh.annotation.HasPermission;
import com.aryankh.annotation.HasRole;
import com.aryankh.constant.Constants;
import com.aryankh.core.RedisTemplate;
import com.aryankh.exception.PremissionNeedHasException;
import com.aryankh.exception.RoleNeedHasException;
import com.fasterxml.jackson.core.type.TypeReference;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.nio.file.AccessDeniedException;
import java.util.List;
import java.util.Objects;

/**
 * @version 1.0
 * @Author AryanKH
 * @Date 2022/6/2 13:49
 * @Default
 */
@Component
@Aspect
public class PermissionAspect {
    @Resource
    private RedisTemplate redisTemplate;

    @Before("@annotation(hasRole)")
    public void roleBfore(JoinPoint joinPoint, HasRole hasRole) {
        // 获得所需要的角色
        String[] needRoles = hasRole.value();
        // 获得拥有的角色
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        String token = request.getHeader(Constants.AUTHORIZATION);
        List<String> hasRoles = redisTemplate.getObject(Constants.ROLE_PREFIX + token, new TypeReference<>() {
        });
        // 只要所需的角色有一个在你拥有的角色中,就放行,否则就不能访问相对应的接口
        boolean flag = false;
        for (String needRole : needRoles) {
            if (hasRoles.contains(needRole)) {
                flag = true;
                break;
            }
        }
        if (!flag){
            throw new RoleNeedHasException("您没有接口所需要的角色");
        }
    }


    @Before("@annotation(hasPermission)")
    public void roleBfore(JoinPoint joinPoint, HasPermission hasPermission) {
        // 获得所需要的角色
        String[] needPressions = hasPermission.value();
        // 获得拥有的权限
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        String token = request.getHeader(Constants.AUTHORIZATION);
        List<String> hasPermissions = redisTemplate.getObject(Constants.PERM_PREFIX + token, new TypeReference<>() {
        });
        // 只要所需的角色有一个在你拥有的角色中,就放行,否则就不能访问相对应的接口
        boolean flag = false;
        for (String needPression : needPressions) {
            if (hasPermissions.contains(needPression)) {
                flag = true;
                break;
            }
        }
        if (!flag){
            throw new PremissionNeedHasException("您没有接口所需要的权限");
        }
    }
}
